package golf.stockinfo.buysellsimulation;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeMap;

import org.joda.time.DateTime;

public class SimulationCommonUtils {
	
	private static int CONDITION_ID_SEQ_INCREMENT = 1000;
	
	public static long getNewConditionId(Connection conn) throws SQLException{
		
		long cacheKey = 1262790898720000l;
		Long output = (Long)GlobalCache.getCache(cacheKey);
		
		if(output == null
				|| output % CONDITION_ID_SEQ_INCREMENT == 0){
			PreparedStatement ps = conn.prepareStatement("SELECT CONDITION_ID_SEQ.nextval FROM DUAL");
			ResultSet rs = ps.executeQuery();
			if(rs.next()){
				output = rs.getLong(1);
			}else{
				throw new RuntimeException("Error can't select sequence from CONDITION_ID_SEQ");
			}
			
			rs.close();
			ps.close();
			
		}else{
			output++;
		}
		
		GlobalCache.addCache(cacheKey, output);
		return output;
	}
	
	public static TreeMap<DateTime, MarketData> loadMarketDataFromDB(
			Connection conn, int smav, String marketName, String currencyPair, String tradingType) throws SQLException{
		
		String cacheKey = "loadMarketDataFrom" + smav + marketName + currencyPair + tradingType;
		
		@SuppressWarnings("unchecked")
		TreeMap<DateTime, MarketData> output = (TreeMap<DateTime, MarketData>) GlobalCache.getCache(cacheKey);
		
		if(output != null){
			return output;
		}else{
			output = new TreeMap<DateTime, MarketData>();
		}
		
        PreparedStatement ps = conn.prepareStatement(
        		"SELECT " +
        		"  TRADING_DATE" +
        		" ,OPEN" +
        		" ,HIGH" +
        		" ,LOW" +
        		" ,CLOSE " +
        		"FROM PRICE_HIST " +
        		"WHERE MARKET_NAME = ? " +
        		"  AND CURRENCY_PAIR = ? " +
        		"  AND TRADING_TYPE = ? " +
        		"ORDER BY TRADING_DATE");
        
        ps.setString(1, marketName);	//EFIN
        ps.setString(2, currencyPair);	//SET
        ps.setString(3, tradingType);	//WEEKLY
        
        ResultSet rsWeekly = ps.executeQuery();
        
        MarketData prevMarketData = null;

		while (rsWeekly.next()) {
			
			MarketData marketData = new MarketData();
			
			DateTime date = new DateTime(rsWeekly.getDate("TRADING_DATE"));
			
			marketData.setDate(rsWeekly.getDate("TRADING_DATE"));
			marketData.setOpenIndex(rsWeekly.getFloat("OPEN"));
			marketData.setHighIndex(rsWeekly.getFloat("HIGH"));
			marketData.setLowIndex(rsWeekly.getFloat("LOW"));
			marketData.setCloseIndex(rsWeekly.getFloat("CLOSE"));
			marketData.setSMAV(smav);
			if(output.size() >= smav - 1){
				float sum = marketData.getCloseIndex();
				Iterator<DateTime> oItr = output.keySet().iterator();
				int i=0;
				while(oItr.hasNext()){
					i++;
					MarketData o = output.get(oItr.next());
					if(i > (output.size() - smav + 1)){
						sum = sum + o.getCloseIndex();
					}
				}
				marketData.setCloseIndexSMAV(sum/smav);
			}
			
			if(output.size() > 0){
				prevMarketData.setNextDate(marketData.getDate());
				prevMarketData = marketData;
			}
			
			prevMarketData = marketData;

			output.put(date, marketData);
		}
			
		rsWeekly.close();
		ps.close();
		
		//To make a mark of item to be clean up for those do not have SMAV for close index
		Iterator<DateTime> oItr = output.keySet().iterator();
		//This has to be defined to avoid ConcurrentModification Exception
		ArrayList<DateTime> tobeDeleted = new ArrayList<DateTime>();
		while(oItr.hasNext()){
			DateTime nextIndx = oItr.next();
			MarketData o = output.get(nextIndx);
			if(o.getCloseIndexSMAV() == 0){
				tobeDeleted.add(nextIndx);
			}
		}
		
		for(DateTime dt:tobeDeleted){
			//This is now really delete the item
			output.remove(dt);
		}
		
		GlobalCache.addCache(cacheKey, output);
		
		return output;
		
	}
	
	public static double roundOff(double toRoundOff, int noOfDigitLeft){
		
		BigDecimal initialValue = new BigDecimal(toRoundOff);
		
		return initialValue.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
		
//		String[] tmpArr = Double.toString(toRoundOff).split("\\.");
//		String fullPart = tmpArr[0];
//		String decimalPart = tmpArr[1];
//		
//		if(decimalPart.length() <= noOfDigitLeft){
//			return toRoundOff;
//		}else if(noOfDigitLeft > 0){
//			return Double.parseDouble(fullPart + "." + decimalPart.substring(0, noOfDigitLeft));
//		}else{
//			return Double.parseDouble(fullPart);
//		}

	}



}
